<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <script>
                    // JavaScript 设计模式是基于已有的通用问题解决方案，可以提高代码的可维护性、可复用性和可测试性。以下是一些常见的JavaScript设计模式：

            // 单例模式：确保一个类只有一个实例，提供一个全局访问点。

            var Singleton = (function() {
                var instance;

                function createInstance() {
                    return {
                        method: function() {
                            console.log('method of singleton');
                        }
                    };
                }

                return {
                    getInstance: function() {
                        if (!instance) {
                            instance = createInstance();
                        }
                        return instance;
                    }
                };
            })();

            var singleton1 = Singleton.getInstance();
            var singleton2 = Singleton.getInstance();
            console.log(singleton1 === singleton2); // true

            // 工厂模式：创建对象的接口，隐藏创建的细节。

            function createCar(model, year, miles) {
                var car = {
                    model: model,
                    year: year,
                    miles: miles,
                    showInfo: function() {
                        console.log(`${this.model} has done ${this.miles} miles`);
                    }
                };
                return car;
            }

            var car1 = createCar('Toyota', 2010, 20000);
            var car2 = createCar('Honda', 2012, 5000);

            // 模块模式：封装并提供接口，防止全局变量污染。

            var myModule = (function() {
                var privateVariable = 'private';

                function privateMethod() {
                    return 'private method';
                }

                return {
                    publicVariable: 'public',
                    publicMethod: function() {
                        return privateVariable + ' ' + privateMethod();
                    }
                };
            })();

            console.log(myModule.publicVariable); // 'public'
            console.log(myModule.publicMethod()); // 'private public private method'

            // 观察者模式：定义对象间一对多的依赖关系，当一个对象改变时，所有依赖的对象都会被自动通知。

            function Observable() {
                this.observers = [];
            }

            Observable.prototype.addObserver = function(observer) {
                this.observers.push(observer);
            };

            Observable.prototype.notify = function(message) {
                this.observers.forEach(function(observer) {
                    observer.update(message);
                });
            };

            function Observer(name) {
                this.name = name;
            }

            Observer.prototype.update = function(message) {
                console.log(this.name + ' received: ' + message);
            };

            var observable = new Observable();
            var observer1 = new Observer('Observer 1');
            var observer2 = new Observer('Observer 2');

            observable.addObserver(observer1);
            observable.addObserver(observer2);

            observable.notify('a notification');
            // Output:
            // Observer 1 received: a notification
            // Observer 2 received: a notification

            // 代理模式：为其他对象提供一种代理以控制对这个对象的访问。

            var proxyImage = (function() {
                var img = new Image();

                img.onload = function() {
                    console.log('Image is loaded!');
                };

                return {
                    setSrc: function(src) {
                        img.src = src;
                    }
                };
            })();

            proxyImage.setSrc('path/to/image.jpg');

            // 装饰器模式：动态地给对象添加额外的职责。

            function Car(model) {
                this.model = model;
            }

            Car.prototype.show = function() {
                return this.model + ' car';
            };

            // function LeatherSeats
        </script>
    </body>
</html>
